package dellstore

import com.googlecode.mapperdao._
import dellstore.model.Customer
import dellstore.model.Order
import dellstore.model.Gender
import dellstore.model.CreditCard
import dellstore.model.Address
import java.util.UUID
import dellstore.model.OrderLine
import org.joda.time.DateTime

/**
 * dellstore sample for postgresql dellstore sample database
 *
 * @author kostantinos.kougios
 *
 *         30 Aug 2011
 */
object Main extends App
{

	import dao.Daos._

	val cmd = args(0)
	println("processing command " + cmd)

	cmd match {
		case "list-categories" =>
			val all = categoryDao.all

			println("id\tcategory")
			println("-----------------------------------------------")
			all.foreach {
				c =>
					println("%d :\t%s".format(c.id, c))
			}
		case "list-products" =>
			val all = productDao.page(1, 20)
			println("id\tproduct")
			println("-----------------------------------------------")
			all.foreach {
				p =>
					println("%d :\t%s".format(p.id, p))
			}
		case "list-customers" =>
			val all = customerDao.page(1, 20)
			println("customers")
			println("-----------------------------------------------")
			printCustomers(all)
		case "customers-by-state" =>
			val all = customerDao.byState(args(1))
			printCustomers(all)
		case "list-orders" =>
			println("id\torders")
			println("-----------------------------------------------")
			printOrders(orderDao.page(1, 20))
		case "orders-by-state" =>
			println("id\torders")
			println("-----------------------------------------------")
			printOrders(orderDao.byState(args(1)))
		case "orders-by-total-price" =>
			println("id\torders")
			println("-----------------------------------------------")
			printOrders(orderDao.byTotal(args(1).toDouble, args(2).toDouble))
		case "add-customer" =>
			val uuid = UUID.randomUUID()

			val customer = new Customer(args(1), args(2),
				Address("25 some street", "some avenue", "Athens", "GR", 85100, "Greece", 2), "email@x.x", "1234567",
				CreditCard(1, "1234 5678 9012 3456", "2011"), "userx" + uuid, "pwd", 22, 25000, Gender.Male)

			// now insert customer and all the embedded entities (Address,CreditCard)
			val inserted = customerDao.create(customer)
			// since customer has an autogenerated id, after inserting it contains a new property: inserted.id
			println("added %d : %s".format(inserted.id, inserted))

			// update the immutable Customer. Because customer is immutable, we can only
			// update by creating a new instance with the new values
			val updatedCustomer = new Customer(args(1), args(2),
				Address("25 some street", "Bromley", "London", "UK", 85100, "UK", 2), "email@x.x", "2345678",
				CreditCard(1, "1234 5678 9012 3456", "2011"), "userx" + uuid, "pwd", 22, 25000, Gender.Male)
			// now update the customer providing the old and new value
			val updated = customerDao.update(inserted, updatedCustomer)
			println("updated %d : %s".format(updated.id, updated))

			val selected = customerDao.retrieve(updated.id).get
			println("retrieved %d : %s".format(selected.id, selected))

		case "add-order" =>
			val uuid = UUID.randomUUID()

			// first create the customer (we could as well read him from the database)
			val customer = customerDao.create(new Customer(args(1), args(2),
				Address("25 some street", "some avenue", "Athens", "GR", 85100, "Greece", 2), "email@x.x", "1234567",
				CreditCard(1, "1234 5678 9012 3456", "2011"), "userx" + uuid, "pwd", 22, 25000, Gender.Male))

			// now get some products that can be ordered by the customer.
			val products = productDao.idRange(1, 5)

			// create the orderlines
			val now = DateTime.now
			val orderLines = List(new OrderLine(-10, null, products.head, 5, now), new OrderLine(-11, null, products(2), 5, now))
			val order = new Order(now, customer, 100.5, 10.5, 90.0, orderLines)

			// this will insert the order, the orderlines and it would update the customer,if it had changed
			val inserted = orderDao.create(order)

			// at some other part of the code we might have the orderId and we would like to print out the order:
			val orderId = inserted.id
			println("Order : %s".format(orderDao.retrieve(orderId)))
	}

	def printCustomers(customers: List[Customer with SurrogateIntId]) {
		customers.foreach {
			printCustomer(_)
		}
	}

	def printCustomer(c: Customer with SurrogateIntId) {
		println("%d :\t%s".format(c.id, c))
	}

	def printOrders(orders: List[Order with SurrogateIntId]) {
		orders.foreach(o => println("%d :\t%s".format(o.id, o)))
	}
}